package com.hfb.mashibing.alip8.juc.c020_01_interview.A1B2C3;

import java.lang.reflect.Field;
import sun.misc.Unsafe;

/**
 *  互联网一线大厂面试题：
 *      徒手写出：2个不同的线程，交替输出A1B2C3。。。
 *
 * 线程排序问题
 * 思路：利用 CAS 和 Unsafe，
 *      分别依次遍历字母队列和数字队列
 */
public class A1B2C3CAS1 {

    private static char[] charsLetter = "ABCDEFGHI".toCharArray();
    private static char[] charsNumber = "123456789".toCharArray();

    private static Unsafe unsafe;
    private static long headOffset;
    private int flag = 0;

    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
        unsafe = unsafeInit();


        headOffset = unsafe.objectFieldOffset(A1B2C3CAS1.class.getDeclaredField("flag"));


        new Thread(()->{
            for (int i = 0; i < charsLetter.length; i++) {
                // 2次CAS是为了保证2个线程的打印顺序
                while (!unsafe.compareAndSwapInt(A1B2C3CAS1.class, headOffset,0,2)) {}
                System.out.print(charsLetter[i]);
                while (!unsafe.compareAndSwapInt(A1B2C3CAS1.class, headOffset,2,1)) {}
            }
            System.out.println();
        }).start();


        new Thread(()->{
            for (int i = 0; i < charsNumber.length; i++) {
                // 2次CAS是为了保证2个线程的打印顺序
                while (!unsafe.compareAndSwapInt(A1B2C3CAS1.class, headOffset,1,2)) {}
                System.out.print(charsNumber[i]);
                while (!unsafe.compareAndSwapInt(A1B2C3CAS1.class, headOffset,2,0)) {}
            }
            System.out.println();
        }).start();

    }

    private static Unsafe unsafeInit () throws NoSuchFieldException, IllegalAccessException {
        Class clazz = Unsafe.class;
        Field f = clazz.getDeclaredField("theUnsafe");
        f.setAccessible(true);
        return (Unsafe) f.get(clazz);
    }
}
